/**
 * 一个包含了{@link O#equals}方法的对象类。
 *
 * 此类提供了对两个对象之间的比较方法。
 *
 * 由于此包中大部分的类都依赖比较方法，但是原生的比较方法（===）并不能完美地解决大部分情况，如需要手动的重写判断方法等。因此提供了这样一个类，并将其
 * 加入到了此包内所有集合的支持范围内。
 *
 * @see Object
 * @version 1.0
 */
import {hash} from "./Hash";

export class Obj extends Object {

  [Symbol.hasInstance](): boolean {
    return false;
  }

  /**
   * 指示其他某个对象是否“等于”这个对象。
   *
   * <strong>强烈建议您重写此方法，以便我们可以准确地相互判断。</strong>
   *
   * @param b 需要被判断的另一个对象
   * @return {boolean} 如果两个对象互相相等，则返回true，否则返回false
   * @version 1.0
   */
  equals(b: Obj): boolean {
    return this === b;
  }

  /**
   * 将该对象转为hashCode。
   *
   * <strong>由于hashCode相同不一定代表两个对象一定相同，因此我们强烈建议您重写此方法以更好的达到区分目的。</strong>
   *
   * @return {number} 此对象的hashcode
   * @version 1.0
   */
  hashCode(): number {
    return hash(this.toString());
  }
}

/**
 * 对两个给定的对象进行比较以判断两者是否相等。
 *
 * 若两个对象继承自{@link O}，则完美会使用{@link O#equals}方法进行比较，否则会使用原生的比较方式（===）。
 *
 * 当在进行数据结构的扩展时，我们建议使用此方法进行比较，而不是{@link O#equals}，因为此方法还能覆盖到基础类型以及其他未继承{@link O}的对象。
 *
 * @param a 需要互相比较的第一个对象
 * @param b 需要互相比较的第二个对象
 * @return {boolean} 如果两个对象比较结果相等，则返回true，否则返回false
 * @see O#equals
 * @version 1.0
 */
export function equalsTo(a: any, b: any): boolean {
  if (a instanceof Obj && b instanceof Obj) {
    return a.equals(b);
  } else {
    return a === b;
  }
}

export default Obj;
